﻿using System;
using System.Collections.Generic;
using Xunit;

namespace UniSender.Test
{
    public class TestClientExceptions
    {
        Exception exc =  new Exception();
        IDictionary<string, object> args = new Dictionary<string, object>() { { "arg1", 1 } };

        void CheckException(UniSenderException testExc, bool checkInner = true)
        {
            if (checkInner)
                Assert.Same(exc, testExc.InnerException);
            Assert.Equal("tt", testExc.Lang);
            Assert.Equal("action", testExc.Method);
            Assert.NotNull(testExc.Args);
            Assert.Equal(1, testExc.Args.Count);
            Assert.Equal(1, testExc.Args["arg1"]);
            Assert.Equal("tt", testExc.Data["UniSender_Lang"]);
            Assert.Equal("action", testExc.Data["UniSender_Method"]);
            Assert.Same(testExc.Args, testExc.Data["UniSender_Args"]);
        }

        [Fact]
        public void TestExceptionInDeserialize()
        {
            var client = new ClientStub("tt", "test")
            {
                Deserializer = new DeserializerStub() { StubDeserialize = s => { throw exc; } }
            };
            var type = typeof(MailList[]);
            var testExc = Assert.Throws<UniSenderParseException>(() =>
            {
                client.Call<MailList[]>("action", args);
            });
            
            CheckException(testExc);
            
            Assert.Equal("{}", testExc.ResponseText);
            Assert.Equal("{}", testExc.Data["UniSender_Response"]);

            Assert.Equal(type, testExc.ExpectedType);
            Assert.Equal(type, testExc.Data["UniSender_ExpectedType"]);
        }

        [Fact]
        public void TestErrorException()
        {
            var client = new ClientStub("tt", "test")
            {
                Deserializer = new DeserializerStub()
                {
                    StubDeserialize = s => new Native.Response<MailList[]>()
                    {
                        error = "Test error",
                        code = "test_error"
                    }
                }
            };
            var type = typeof(MailList[]);
            var testExc = Assert.Throws<UniSenderErrorException>(() =>
            {
                client.Call<MailList[]>("action", args);
            });

            CheckException(testExc, false);

            Assert.Equal("Test error", testExc.Error);
            Assert.Equal("Test error", testExc.Data["UniSender_Error"]);

            Assert.Equal("test_error", testExc.Code);
            Assert.Equal("test_error", testExc.Data["UniSender_Code"]);
        }
    }
}
